<template>
  <view class="upload-container">
    <button class="upload-trigger" @click="selectFile">
      <text class="upload-icon">📁</text>
      <text class="upload-text">{{ buttonText || "选择文件" }}</text>
    </button>

    <view v-if="selectedFile" class="file-preview">
      <view class="file-info">
        <text class="file-name">{{ selectedFile.name }}</text>
        <text class="file-size">{{ formatFileSize(selectedFile.size) }}</text>
      </view>
      <button class="remove-btn" @click="removeFile">✕</button>
    </view>

    <button
      v-if="selectedFile"
      class="upload-btn"
      :disabled="uploading"
      @click="uploadFile"
    >
      <text v-if="!uploading">{{ uploadText || "开始上传" }}</text>
      <text v-else>上传中... {{ progress }}%</text>
    </button>

    <view v-if="uploadStatus" class="upload-status" :class="statusClass">
      <text class="status-text">{{ uploadStatus }}</text>
    </view>
  </view>
</template>

<script setup>
import { ref, computed } from "vue";

// API基础URL - 严格按照后端接口地址
const API_BASE_URL =
  import.meta.env.VITE_API_BASE_URL || "http://admin-yzy-two.wudkmao.top/api/v1";

// Props
const props = defineProps({
  buttonText: {
    type: String,
    default: "选择文件",
  },
  uploadText: {
    type: String,
    default: "开始上传",
  },
  autoUpload: {
    type: Boolean,
    default: false,
  },
});

// Emits
const emit = defineEmits(["success", "error", "progress"]);

// 响应式数据
const selectedFile = ref(null);
const uploading = ref(false);
const progress = ref(0);
const uploadStatus = ref("");

// 计算属性
const statusClass = computed(() => {
  if (uploadStatus.value.includes("成功")) return "status-success";
  if (uploadStatus.value.includes("失败")) return "status-error";
  return "status-info";
});

// 微信小程序端文件选择 - 专门为微信小程序端优化
const selectFile = async () => {
  try {
    console.log("微信小程序端开始选择文件...");

    // 优先尝试使用chooseMessageFile（微信聊天文件）
    const res = await uni.chooseMessageFile({
      count: 1,
      type: "file",
      extension: ["pdf", "doc", "docx", "txt", "md"],
    });

    if (res.tempFiles && res.tempFiles.length > 0) {
      const file = res.tempFiles[0];
      console.log("微信小程序原始文件对象:", file);

      // 验证文件
      if (!validateFile(file)) {
        throw new Error("文件验证失败");
      }

      // 创建微信小程序专用的文件对象
      const weixinFile = {
        name: file.name || getFileNameFromPath(file.path),
        size: file.size || 0,
        type: file.type || "application/octet-stream",
        path: file.path,
        tempFilePath: file.path,
      };

      console.log("微信小程序文件选择结果:", weixinFile);
      selectedFile.value = weixinFile;

      if (props.autoUpload) {
        uploadFile();
      }
    }
  } catch (chooseError) {
    console.log("chooseMessageFile失败，尝试chooseFile:", chooseError);

    try {
      // 如果chooseMessageFile失败，尝试使用chooseFile
      const res = await uni.chooseFile({
        count: 1,
        type: "all",
        extension: [".pdf", ".doc", ".docx", ".txt", ".md"],
      });

      if (res.tempFiles && res.tempFiles.length > 0) {
        const file = res.tempFiles[0];
        console.log("微信小程序chooseFile原始文件对象:", file);

        // 验证文件
        if (!validateFile(file)) {
          throw new Error("文件验证失败");
        }

        // 创建微信小程序专用的文件对象
        const weixinFile = {
          name: file.name || getFileNameFromPath(file.path),
          size: file.size || 0,
          type: file.type || "application/octet-stream",
          path: file.path,
          tempFilePath: file.path,
        };

        console.log("微信小程序chooseFile结果:", weixinFile);
        selectedFile.value = weixinFile;

        if (props.autoUpload) {
          uploadFile();
        }
      }
    } catch (chooseFileError) {
      console.error("微信小程序文件选择完全失败:", chooseFileError);
      uni.showToast({
        title: "文件选择失败，请重试",
        icon: "none",
      });
    }
  }
};

// 微信小程序端文件验证 - 专门为微信小程序端优化
const validateFile = (file) => {
  console.log("微信小程序端文件验证开始:", file);

  // 验证文件路径
  if (!file.path) {
    console.error("文件验证失败：文件路径无效");
    uni.showToast({
      title: "文件路径无效",
      icon: "none",
    });
    return false;
  }

  // 验证文件类型
  const fileName = file.name || getFileNameFromPath(file.path);
  const allowedTypes = ["pdf", "doc", "docx", "txt", "md"];
  const fileExt = fileName.split(".").pop()?.toLowerCase();
  if (!allowedTypes.includes(fileExt)) {
    console.error("文件验证失败：不支持的文件类型", fileExt);
    uni.showToast({
      title: "不支持的文件类型，请选择PDF、Word、TXT或MD文件",
      icon: "none",
    });
    return false;
  }

  return true;
};

// 从路径中提取文件名
const getFileNameFromPath = (path) => {
  if (!path) return "";
  const parts = path.split("/");
  const fileName = parts[parts.length - 1];
  return fileName || `文件_${Date.now()}`;
};

// 移除文件
const removeFile = () => {
  selectedFile.value = null;
  progress.value = 0;
  uploadStatus.value = "";
};

// 微信小程序端文件上传 - 严格按照后端DocumentController.cs接口实现
const uploadFile = async () => {
  if (!selectedFile.value || uploading.value) return;

  try {
    uploading.value = true;
    progress.value = 0;
    uploadStatus.value = "准备上传...";

    const file = selectedFile.value;
    console.log("微信小程序端开始上传文件:", file);

    if (!file.path) {
      throw new Error("微信小程序端缺少文件路径");
    }

    // 获取认证token
    const token =
      uni.getStorageSync("token") || uni.getStorageSync("accessToken");
    if (!token) {
      throw new Error("未找到认证token，请先登录");
    }

    progress.value = 10;
    uploadStatus.value = "正在上传...";

    return new Promise((resolve, reject) => {
      // 严格按照后端接口使用uni.uploadFile
      // 后端接口: [HttpPost("upload")] public async Task<IActionResult> UploadDocument([FromForm] IFormFile file, [FromForm] string? fileName = null)
      uni.uploadFile({
        url: `${API_BASE_URL}/document/upload`, // 严格按照后端接口地址
        filePath: file.path,
        name: "file", // 对应 [FromForm] IFormFile file
        formData: {
          fileName: file.name, // 对应 [FromForm] string? fileName = null
        },
        header: {
          Authorization: `Bearer ${token}`,
          // 不要手动设置Content-Type，让uni-app自动设置
        },
        success: (res) => {
          console.log("微信小程序上传成功:", res);

          progress.value = 100;
          uploadStatus.value = "上传完成";

          try {
            const data = JSON.parse(res.data);

            // 处理上传结果
            if (data.id || data.code === 200 || data.code === 201) {
              uploadStatus.value = "上传成功";
              emit("success", data);

              setTimeout(() => {
                selectedFile.value = null;
                uploadStatus.value = "";
                progress.value = 0;
              }, 2000);
            } else {
              throw new Error(data.message || data.error || "上传失败");
            }

            resolve(data);
          } catch (e) {
            reject(new Error("服务器响应格式错误"));
          }
        },
        fail: (error) => {
          console.error("微信小程序上传失败:", error);
          reject(new Error(`上传失败: ${error.errMsg || "未知错误"}`));
        },
      });
    });
  } catch (error) {
    console.error("微信小程序端上传失败:", error);
    uploadStatus.value = `上传失败: ${error.message}`;
    emit("error", error);
    throw error;
  } finally {
    uploading.value = false;
  }
};

// 工具函数
const formatFileSize = (bytes) => {
  if (!bytes) return "0 B";
  const k = 1024;
  const sizes = ["B", "KB", "MB", "GB"];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
};

// 暴露方法给父组件
defineExpose({
  selectFile,
  uploadFile,
  removeFile,
});
</script>

<style lang="scss" scoped>
.upload-container {
  display: flex;
  flex-direction: column;
  gap: 20rpx;
}

.upload-trigger {
  background: rgba(255, 255, 255, 0.2);
  border: 2rpx dashed rgba(255, 255, 255, 0.5);
  border-radius: 20rpx;
  padding: 60rpx;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20rpx;
  transition: all 0.3s ease;
}

.upload-trigger:active {
  transform: scale(0.98);
}

.upload-icon {
  font-size: 64rpx;
  color: rgba(255, 255, 255, 0.7);
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

.upload-text {
  font-size: 32rpx;
  color: rgba(255, 255, 255, 0.8);
}

.file-preview {
  background: rgba(255, 255, 255, 0.1);
  border-radius: 20rpx;
  padding: 30rpx;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.file-info {
  display: flex;
  flex-direction: column;
  gap: 10rpx;
}

.file-name {
  font-size: 28rpx;
  color: white;
  font-weight: bold;
}

.file-size {
  font-size: 24rpx;
  color: rgba(255, 255, 255, 0.7);
}

.remove-btn {
  background: rgba(255, 255, 255, 0.2);
  border: none;
  border-radius: 50%;
  width: 60rpx;
  height: 60rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-size: 32rpx;
}

.upload-btn {
  background: #667eea;
  color: white;
  border: none;
  border-radius: 50rpx;
  padding: 30rpx;
  font-size: 32rpx;
}

.upload-btn:disabled {
  background: #ccc;
}

.upload-status {
  padding: 20rpx;
  border-radius: 10rpx;
  text-align: center;
  font-size: 28rpx;
}

.status-success {
  background: rgba(76, 175, 80, 0.2);
  color: #4caf50;
}

.status-error {
  background: rgba(244, 67, 54, 0.2);
  color: #f44336;
}

.status-info {
  background: rgba(33, 150, 243, 0.2);
  color: #2196f3;
}
</style>
